package control.elements;

import control.elements.helpers.ElementType;

/**
 * 
 * @author Scott
 *
 */
public class CallerAbilities {

	/**
	 * Summons Carbuncle.
	 * @return
	 */
	public static Avatar summonCarby(int the_level){
		Avatar Carbuncle = new Avatar(the_level, "Carbuncle");	
		return Carbuncle;
	}
	
	/**
	 * 
	 */
	public static Avatar releasePet(int the_level) {
		Avatar Release = new Avatar(the_level, "None");
		return Release;
	}
	
	/**
	 * Summons Fenrir.
	 * @return
	 */
	public static Avatar summonFenrir(int the_level){
		Avatar Fenrir = new Avatar(the_level, "Fenrir");		
		return Fenrir;
	}
	
	/**
	 * Summons Diabolos.
	 * @return
	 */
	public static Avatar summonDiabolos(int the_level){
		Avatar Diabolos = new Avatar(the_level, "Diabolos");	
		return Diabolos;
	}
	
	/**
	 * Summons Ifrit.
	 * @return
	 */
	public static Avatar summonIfrit(int the_level){
		Avatar Ifrit = new Avatar(the_level, "Ifrit");		
		return Ifrit;
	}
	
	/**
	 * Summons Titan.
	 * @return
	 */
	public static Avatar summonTitan(int the_level){
		Avatar Titan = new Avatar(the_level, "Titan");	
		return Titan;
		
	}
	
	/**
	 * Summons Leviathan.
	 * @return
	 */
	public static Avatar summonLevi(int the_level){
		Avatar Leviathan = new Avatar(the_level, "Leviathan");		
		return Leviathan;
	}
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonGaru(int the_level){
		Avatar Garuda = new Avatar (the_level, "Garuda");	
		return Garuda;
	}
	
	/**
	 * Summons Shiva.
	 * @return
	 */
	public static Avatar summonShiva(int the_level){
		Avatar Shiva = new Avatar (the_level, "Shiva");
		return Shiva;
	}
	
	/**
	 * Summons Ramuh.
	 * @return
	 */
	public static Avatar summonRamuh(int the_level){
		Avatar Ramuh = new Avatar (the_level, "Ramuh");
		return Ramuh;
	}
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonLightSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Light Spirit");
		return Spirit;
	}
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonDarkSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Dark Spirit");
		return Spirit;
	}	
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonFireSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Fire Spirit");
		return Spirit;
	}
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonWaterSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Water Spirit");
		return Spirit;
	}
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonWindSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Wind Spirit");
		return Spirit;
	}
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonIceSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Ice Spirit");
		return Spirit;
	}	
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonEarthSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Earth Spirit");
		return Spirit;
	}
	
	/**
	 * 
	 * @param the_level
	 * @return
	 */
	public static Avatar summonThunderSpirit(int the_level) {
		Avatar Spirit = new Avatar(the_level,"Thunder Spirit");
		return Spirit;
	}
	
	/**
	 * Calculates the MP returned by a Caller using elemental siphon.
	 * 
	 * @param the_skill The current summoning magic skill.
	 * @param the_pants Determines if the caller is wearing 
	 * the Tatsumaki Sitagoromo.
	 * @param the_feet1 Determines if the caller is wearing the Caller's
	 * Pigaches +1.
	 * @param the_feet2 Determiens if the caller is wearing the Caller's
	 * Pigaches +2.
	 * @param the_cape Determines if the caller is wearing the Twilight cape.
	 * @param the_element The current element of the pet.
	 * @param day The element of the day of the week.
	 * @param w1 The element of the primary weather.
	 * @param w2 The element of the auxilary weather.
	 * 
	 * @return The final mp gained by using elemental siphon.
	 */
	public static double elementalSiphon(final int the_skill,
			final boolean the_pants,
			final boolean the_feet1,
			final boolean the_feet2,
			final boolean the_cape, 
			final boolean the_cape2,
			final ElementType the_element,
			final ElementType day, 
			final ElementType w1, 
			final ElementType w2) {
		int result;
		result = the_skill - 50;
		if(the_pants) {
			result = result + 20; //Tatsumaki Sitagoromo.
		}
		if(the_feet1) {
			result = result + 25; // Caller's Pigaches +1.
		} else if (the_feet2) {
			result = result + 40; // Caller's Pigaches +2.
		}
		if(the_cape2) {
			result = result + 30; // Conveyance cape.
		}
		double bonus = determineBonus(the_cape, the_element, day, w1, w2);
		return Math.floor(result * bonus);
	}

	/**
	 * Calculates the bonus applied to elemental siphon given the weather
	 * and the day is alligned with, or weak to, the current element of the pet.
	 * 
	 * @param theElement The current pets element.
	 * @param day The element of the day.
	 * @param w1 The element of the primary weather.
	 * @param w2 The element of the auxilary weather.
	 * @return Returns the value of the mp returned after the bonus is applied.
	 */
	private static double determineBonus(final boolean the_cape,
			final ElementType theElement,
			final ElementType day, 
			final ElementType w1, 
			final ElementType w2) {
		double bonus;
		
		if(theElement.isSameAs(day)){
			if(theElement.isSameAs(w1)) {
				if(theElement.isSameAs(w2)) {
					bonus = 1.35;
				} else {
					bonus = 1.20;
				} 
			} else if( theElement.isWeakTo(w1)) {
				 if( theElement.isWeakTo(w2)) {
					 bonus = .90;
				 } else {
					 bonus = 1.0;
				 }
			} else {
				bonus = 1.10;
			}
		} else if(theElement.isWeakTo(day)) {
			if(theElement.isSameAs(w1)) {
				if(theElement.isSameAs(w2)) {
					bonus = 1.15;
				} else {
					bonus = 1.10;
				}
			} else if(theElement.isWeakTo(w1)) {
				if(theElement.isWeakTo(w2)) {
					bonus = 0.65;
				} else {
					bonus = 0.80;
				}
			} else {
				bonus = 0.90;
			}
		} else {
			if(theElement.isSameAs(w1)) {
				if(theElement.isSameAs(w2)) {
					bonus = 1.25;
				} else {
					bonus = 1.10;
				}
			} else if( theElement.isWeakTo(w1)){
				if(theElement.isWeakTo(w2)) {
					bonus = 0.75;
				} else {
					bonus = 0.90;
				}
			} else {
				bonus = 1.00;
			}
		}
		
		//Twilight Cape Bonus
		if(the_cape && (theElement.isSameAs(day) || theElement.isSameAs(w1))){
			bonus = bonus + 0.05;
		}
		return bonus;
	}

}
